package com.keli.dt.analyzer;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

import com.keli.common.DateFormatter;
import com.keli.dt.algorithm.RoadReportAlgo;
import com.keli.dt.model.LaneReport;
import com.keli.dt.model.RoadReport;

public class RoadReportHelper {
	// 非机动车类型，1行人，2非机动车
	public static final String[] NONMOTOR_TYPE = { "1", "2" };
	// 机动车类型，3=小车=02，4=大车=01
	public static final String[] MOTOR_TYPE = { "01", "02" };

	// 设备类型
	String DETECT_CLASS;
	// 路段编号
	BigDecimal ROAD_ID;
	// 有数据的车道集合
	HashSet<String> laneSet;
	// 出行机动车的车道集合
	HashSet<String> motorLaneSet;
	// 出行非机动车的车道集合
	HashSet<String> nonmotorLaneSet;	
	// 非机动车流量总和
	BigDecimal VOLUME_NONMOTOR_SUM;
	// 机动车流量总和
	BigDecimal VOLUME_MOTOR_SUM;
	// 机动车速度总和
	BigDecimal SPEED_MOTOR_SUM;
	// 机动车车流密度总和
	double densitySum;
	// 最大采集时间
	String maxCollectDate;
	// 机动车车道记录列表
	List<LaneReport> motorLaneReports;
	// 非机动车车道记录列表
	List<LaneReport> nonmotorLaneReports;
		
	/**
	 * 判断是否为非机动车
	 * @param VEHICLE_CLASS 车辆类型
	 * @return
	 */
	public static boolean isNONMOTOR_TYPE(String VEHICLE_CLASS) {
		return find(VEHICLE_CLASS, NONMOTOR_TYPE);
	}
	
	/**
	 * 判断是否为机动车
	 * @param VEHICLE_CLASS 车辆类型
	 * @return
	 */
	public static boolean isMOTOR_TYPE(String VEHICLE_CLASS) {
		return find(VEHICLE_CLASS, MOTOR_TYPE);
	}
	
	/**
	 * 查找关键字
	 * @param key 关键字
	 * @param list 要查找的数组
	 * @return
	 */
	public static boolean find(String key, String[] list) {
		for (String i: list) {
			if (key.equals(i)) {
				return true;
			}
		}
		return false;
	}

	private RoadReportHelper() {
		laneSet = new HashSet<String>();
		motorLaneSet = new HashSet<String>();
		nonmotorLaneSet = new HashSet<String>();
		VOLUME_NONMOTOR_SUM = new BigDecimal(0);
		VOLUME_MOTOR_SUM = new BigDecimal(0);
		SPEED_MOTOR_SUM = new BigDecimal(0);
		densitySum = 0;
		motorLaneReports = new ArrayList<LaneReport>();
		nonmotorLaneReports = new ArrayList<LaneReport>();
		maxCollectDate = null;
	}

	public RoadReportHelper(LaneReport laneReport) {
		this(); // 调用无参构造方法
		DETECT_CLASS = laneReport.getDETECT_CLASS();
		ROAD_ID = laneReport.getROAD_ID();
		addLaneReport(laneReport);
		maxCollectDate = laneReport.getCOLLEC_DATETIME();
	}
	
	/**
	 * 设置最大采集时间
	 * @param date 采集时间
	 */
	private void setMaxCollectDate(String date) {
		if (maxCollectDate == null) {
			maxCollectDate = date;
		} else {
			if (DateFormatter.max(date, maxCollectDate)) {
				maxCollectDate = date;
			}
		}
	}
	
	/**
	 * 添加车道过车记录
	 * @param laneReport
	 */
	public void addLaneReport(LaneReport laneReport) {
		setMaxCollectDate(laneReport.getCOLLEC_DATETIME());
		String lane = laneReport.getLANE();
		laneSet.add(lane);
		String VEHICLE_CLASS = laneReport.getVEHICLE_CLASS();
		if (isNONMOTOR_TYPE(VEHICLE_CLASS)) {
			nonmotorLaneSet.add(lane);
			VOLUME_NONMOTOR_SUM = VOLUME_NONMOTOR_SUM.add(laneReport.getVOLUME());
			nonmotorLaneReports.add(laneReport);
		} else if (isMOTOR_TYPE(VEHICLE_CLASS)) {
			motorLaneSet.add(lane);
			VOLUME_MOTOR_SUM = VOLUME_MOTOR_SUM.add(laneReport.getVOLUME());
			SPEED_MOTOR_SUM = SPEED_MOTOR_SUM.add(laneReport.getSPEED());
			densitySum += Double.parseDouble(laneReport.getDENSITY());
			motorLaneReports.add(laneReport);
		}		
	}

	public String getDETECT_CLASS() {
		return DETECT_CLASS;
	}

	public void setDETECT_CLASS(String DETECT_CLASS) {
		this.DETECT_CLASS = DETECT_CLASS;
	}

	public BigDecimal getROAD_ID() {
		return ROAD_ID;
	}

	public void setROAD_ID(BigDecimal ROAD_ID) {
		this.ROAD_ID = ROAD_ID;
	}

	/*
	 * 获取路段机动车平均速度
	 */
	public BigDecimal getSPEED_MOTOR_AVG() {
		double sum = SPEED_MOTOR_SUM.doubleValue();
		double avg = sum / motorLaneSet.size();
		String num = String.valueOf(avg).substring(0, 3);
		if (num.endsWith(".")) {
			num = String.valueOf(avg).substring(0, 4);
		}
		return new BigDecimal(num);
	}
	
	/**
	 * 计算平均车流密度
	 * @return
	 */
	public String getAverageDensity() {
		String den = String.valueOf(densitySum / motorLaneSet.size());
		int maxLength = 10;		// 最大长度限制
		if (den.length() <= maxLength) {
			return den;
		}
		return den.substring(0, maxLength);
	}
	
	public RoadReport toRoadReport() {
		RoadReport rr = new RoadReport();
		rr.setDETECT_CLASS(DETECT_CLASS);
		rr.setROAD_ID(ROAD_ID);
		rr.setVOLUME_NONMOTOR(VOLUME_NONMOTOR_SUM);
		int nonmotorLaneSize = nonmotorLaneSet.size();
		if (nonmotorLaneSize > 0) {
			rr.setFLOW_NONMOTOR(RoadReportAlgo.flow(VOLUME_NONMOTOR_SUM, nonmotorLaneSize));
		}
		rr.setVOLUME_MOTOR(VOLUME_MOTOR_SUM);
		int motorLaneSize = motorLaneSet.size();
		if (motorLaneSize > 0) {
			rr.setFLOW_MOTOR(RoadReportAlgo.flow(VOLUME_MOTOR_SUM, motorLaneSize));
		}
		rr.setSPEED(getSPEED_MOTOR_AVG());
		rr.setDENSITY(getAverageDensity());
		rr.setCOLLEC_DATETIME(maxCollectDate);
		rr.setCOLLEC_TIME(maxCollectDate);
		
		BigDecimal speedANA = RoadReportAlgo.calcSpeedANA(rr.getSPEED(), rr.getFLOW_MOTOR(), rr.getDENSITY());
		rr.setSPEED_ANA(speedANA);
		
		return rr;
	}
}
